TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
tmpl_sources = \
+ tmpl/animation.sgml
tmpl/creating.sgml \
tmpl/file-loading.sgml \
tmpl/from-drawables.sgml \
<USER_FUNCTION>
<NAME>ModuleUpdatedNotifyFunc</NAME>
<RETURNS>void </RETURNS>
-GdkPixbuf *pixbuf, gpointer user_data, guint x, guint y, guint width, guint height
+GdkPixbuf *pixbuf, gpointer user_data,
+ guint x, guint y,
+ guint width, guint height
</USER_FUNCTION>
<STRUCT>
<NAME>GdkPixbufModule</NAME>
gboolean (* format_check) (guchar *buffer, int size);
GModule *module;
GdkPixbuf *(* load) (FILE *f);
- GdkPixbuf *(* load_xpm_data) (const gchar **data);
+ GdkPixbuf *(* load_xpm_data) (const char **data);
/* Incremental loading */
- gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, gpointer user_data);
- void (* stop_load) (gpointer context);
- gboolean (* load_increment)(gpointer context, const gchar *buf, guint size);
+
+ gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func,
+ ModuleUpdatedNotifyFunc update_func,
+ gpointer user_data);
+ void (* stop_load) (gpointer context);
+ gboolean (* load_increment) (gpointer context, const guchar *buf, guint size);
/* Animation loading */
GdkPixbufAnimation *(* load_animation) (FILE *f);
<FUNCTION>
<NAME>gdk_pixbuf_get_module</NAME>
<RETURNS>GdkPixbufModule *</RETURNS>
-gchar *buffer,gint size
+guchar *buffer, guint size
</FUNCTION>
<FUNCTION>
<NAME>gdk_pixbuf_load_module</NAME>
<FUNCTION>
<NAME>gdk_pixbuf_loader_write</NAME>
<RETURNS>gboolean </RETURNS>
-GdkPixbufLoader *loader,const gchar *buf,size_t count
+GdkPixbufLoader *loader,const guchar *buf,size_t count
</FUNCTION>
<FUNCTION>
<NAME>gdk_pixbuf_loader_get_pixbuf</NAME>
<STRUCT>
<NAME>GdkPixbufAnimation</NAME>
</STRUCT>
-<ENUM>
-<NAME>GdkPixbufFrameAction</NAME>
-typedef enum
-{
- GDK_PIXBUF_FRAME_RETAIN,
- GDK_PIXBUF_FRAME_DISPOSE,
- GDK_PIXBUF_FRAME_REVERT
-} GdkPixbufFrameAction;
-</ENUM>
<STRUCT>
<NAME>GdkPixbuf</NAME>
-struct GdkPixbuf
-{
+struct GdkPixbuf {
/* Reference count */
int ref_count;
ArtPixBuf *art_pixbuf;
};
</STRUCT>
+<ENUM>
+<NAME>GdkPixbufFrameAction</NAME>
+typedef enum {
+ GDK_PIXBUF_FRAME_RETAIN,
+ GDK_PIXBUF_FRAME_DISPOSE,
+ GDK_PIXBUF_FRAME_REVERT
+} GdkPixbufFrameAction;
+</ENUM>
<STRUCT>
<NAME>GdkPixbufFrame</NAME>
-struct GdkPixbufFrame
-{
+struct GdkPixbufFrame {
+ /* The pixbuf with this frame's image data */
GdkPixbuf *pixbuf;
- gushort x_offset;
- gushort y_offset;
- guint delaytime;
+ /* Offsets for overlaying onto the animation's area */
+ int x_offset;
+ int y_offset;
+
+ /* Frame duration in ms */
+ int delay_time;
+
+ /* Overlay mode */
GdkPixbufFrameAction action;
};
</STRUCT>
<STRUCT>
<NAME>GdkPixbufAnimation</NAME>
-struct GdkPixbufAnimation
-{
+struct GdkPixbufAnimation {
+ /* Reference count */
+ int ref_count;
+
+ /* Number of frames */
int n_frames;
+
+ /* List of GdkPixbufFrame structures */
GList *frames;
};
</STRUCT>
<FUNCTION>
<NAME>gdk_pixbuf_new_from_file</NAME>
<RETURNS>GdkPixbuf *</RETURNS>
-const char *filename
+const char *filename
</FUNCTION>
<FUNCTION>
<NAME>gdk_pixbuf_new_from_data</NAME>
<FUNCTION>
<NAME>gdk_pixbuf_new_from_xpm_data</NAME>
<RETURNS>GdkPixbuf *</RETURNS>
-const gchar **data
+const char **data
</FUNCTION>
<FUNCTION>
<NAME>gdk_pixbuf_add_alpha</NAME>
<FUNCTION>
<NAME>gdk_pixbuf_animation_new_from_file</NAME>
<RETURNS>GdkPixbufAnimation *</RETURNS>
-const char *filename
+const char *filename
+</FUNCTION>
+<FUNCTION>
+<NAME>gdk_pixbuf_animation_ref</NAME>
+<RETURNS>void </RETURNS>
+GdkPixbufAnimation *animation
</FUNCTION>
<FUNCTION>
-<NAME>gdk_pixbuf_animation_destroy</NAME>
+<NAME>gdk_pixbuf_animation_unref</NAME>
<RETURNS>void </RETURNS>
-GdkPixbufAnimation *animation,gboolean free_frames
+GdkPixbufAnimation *animation
</FUNCTION>
<MACRO>
<NAME>GNOME_TYPE_CANVAS_PIXBUF</NAME>
</SECTION>
<SECTION>
-<FILE>gnome-canvas-pixbuf</FILE>
-GNOME_CANVAS_PIXBUF
-<TITLE>GnomeCanvasPixbuf</TITLE>
-<SUBSECTION Standard>
-GNOME_TYPE_CANVAS_PIXBUF
-GNOME_IS_CANVAS_PIXBUF
-gnome_canvas_pixbuf_get_type
-GNOME_CANVAS_PIXBUF_CLASS
-GNOME_IS_CANVAS_PIXBUF_CLASS
-<SUBSECTION Private>
-GnomeCanvasPixbuf
+<FILE>animation</FILE>
+GdkPixbufFrameAction
+GdkPixbufFrame
+GdkPixbufAnimation
+gdk_pixbuf_animation_new_from_file
+gdk_pixbuf_animation_ref
+gdk_pixbuf_animation_unref
</SECTION>
<SECTION>
gdk_pixbuf_loader_new
gdk_pixbuf_loader_write
gdk_pixbuf_loader_get_pixbuf
+gdk_pixbuf_loader_get_animation
gdk_pixbuf_loader_close
<SUBSECTION Standard>
GDK_TYPE_PIXBUF_LOADER
<SUBSECTION Private>
GdkPixbufLoader
</SECTION>
+
+<SECTION>
+<FILE>gnome-canvas-pixbuf</FILE>
+GNOME_CANVAS_PIXBUF
+<TITLE>GnomeCanvasPixbuf</TITLE>
+<SUBSECTION Standard>
+GNOME_TYPE_CANVAS_PIXBUF
+GNOME_IS_CANVAS_PIXBUF
+gnome_canvas_pixbuf_get_type
+GNOME_CANVAS_PIXBUF_CLASS
+GNOME_IS_CANVAS_PIXBUF_CLASS
+<SUBSECTION Private>
+GnomeCanvasPixbuf
+</SECTION>
<!entity gdk-pixbuf-rendering SYSTEM "sgml/rendering.sgml">
<!entity gdk-pixbuf-from-drawables SYSTEM "sgml/from-drawables.sgml">
<!entity gdk-pixbuf-util SYSTEM "sgml/util.sgml">
-<!entity GnomeCanvasPixbuf SYSTEM "sgml/gnome-canvas-pixbuf.sgml">
+<!entity gdk-pixbuf-animation SYSTEM "sgml/animation.sgml">
<!entity GdkPixbufLoader SYSTEM "sgml/gdk-pixbuf-loader.sgml">
+<!entity GnomeCanvasPixbuf SYSTEM "sgml/gnome-canvas-pixbuf.sgml">
]>
<book>
&gdk-pixbuf-rendering;
&gdk-pixbuf-from-drawables;
&gdk-pixbuf-util;
- &GnomeCanvasPixbuf;
+ &gdk-pixbuf-animation;
&GdkPixbufLoader;
+ &GnomeCanvasPixbuf;
</reference>
</book>
--- /dev/null
+<!-- ##### SECTION Title ##### -->
+Animations
+
+<!-- ##### SECTION Short_Description ##### -->
+Animations as multi-frame structures.
+
+<!-- ##### SECTION Long_Description ##### -->
+ <para>
+ The GdkPixbuf library provides a simple mechanism to load and
+ represent animations, primarily animated GIF files. Animations
+ are represented as lists of #GdkPixbufFrame structures. Each
+ frame structure contains a #GdkPixbuf structure and information
+ about the frame's overlay mode and duration.
+ </para>
+
+
+<!-- ##### SECTION See_Also ##### -->
+ <para>
+ #GdkPixbufLoader
+ </para>
+
+
+<!-- ##### ENUM GdkPixbufFrameAction ##### -->
+ <para>
+
+ </para>
+
+@GDK_PIXBUF_FRAME_RETAIN:
+@GDK_PIXBUF_FRAME_DISPOSE:
+@GDK_PIXBUF_FRAME_REVERT:
+
+<!-- ##### STRUCT GdkPixbufFrame ##### -->
+ <para>
+ This structure describes a frame in a #GdkPixbufAnimation. Each
+ frame consists of a #GdkPixbuf, an offset of the frame within the
+ animation's bounding box, a duration, and an overlay mode or
+ action.
+ </para>
+
+@pixbuf: The frame's image contents.
+@x_offset: X offset of the frame inside the animation's bounding box.
+@y_offset: Y offset of the frame inside the animation's bounding box.
+@delay_time: Duration of the frame in milliseconds.
+@action: Overlay mode.
+
+<!-- ##### STRUCT GdkPixbufAnimation ##### -->
+ <para>
+ This structure describes an animation, which is represented as a
+ list of #GdkPixbufFrame structures.
+ </para>
+
+@ref_count: Reference count.
+@n_frames: Number of frames in the animation.
+@frames: List of #GdkPixbufFrame structures.
+
+<!-- ##### FUNCTION gdk_pixbuf_animation_new_from_file ##### -->
+<para>
+
+</para>
+
+@filename:
+@Returns:
+
+
+<!-- ##### FUNCTION gdk_pixbuf_animation_ref ##### -->
+<para>
+
+</para>
+
+@animation:
+
+
+<!-- ##### FUNCTION gdk_pixbuf_animation_unref ##### -->
+<para>
+
+</para>
+
+@animation:
+
+
+<!--
+Local variables:
+mode: sgml
+sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
+End:
+-->
transferred from the X server to the client program and converted.
</para>
-
<!-- ##### SECTION See_Also ##### -->
<para>
#GdkPixbuf, gdk_image_get()
</para>
-
<!-- ##### FUNCTION gdk_pixbuf_get_from_drawable ##### -->
<para>
@height:
@Returns:
-
<!--
Local variables:
mode: sgml
sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
End:
-->
+
+
@Returns:
+<!-- ##### FUNCTION gdk_pixbuf_loader_get_animation ##### -->
+<para>
+
+</para>
+
+@loader:
+@Returns:
+
+
<!-- ##### FUNCTION gdk_pixbuf_loader_close ##### -->
<para>
@dest_y:
@width:
@height:
-@alpha_threshold:
-<!--
+@alpha_threshold: <!--
Local variables:
mode: sgml
sgml-parent-document: ("../gdk-pixbuf.sgml" "book" "refsect2" "")
@g:
@b:
@Returns:
-
<!--
Local variables:
mode: sgml
+2000-01-01 Federico Mena Quintero <federico@helixcode.com>
+
+ * gdk-pixbuf/gdk-pixbuf.h (GdkPixbufAnimation): Added reference
+ counting to animations. A web browser may want to share a single
+ copy of an animated GIF if it appears multiple times in a web
+ page, for example.
+
+ * gdk-pixbuf/gdk-pixbuf-animation.c: New file. Moved the
+ animation functions here.
+ (gdk_pixbuf_animation_new_from_file): Prettified. Return a NULL
+ animation if the loader does not support multiframe loading and
+ the single-frame load returned NULL. Check that the filename is
+ not NULL. Updated inline documentation.
+ (gdk_pixbuf_animation_ref): New function.
+ (gdk_pixbuf_animation_unref): New function.
+ Removed gdk_pixbuf_animation_destroy() in favor of reference
+ counting.
+
+ * gdk-pixbuf/gdk-pixbuf-io.c (gdk_pixbuf_new_from_file):
+ Prettified. Made ref_count assertion more paranoid. Check that
+ the filename is not NULL.
+ (gdk_pixbuf_get_module): Use guchar * and guint for buffer and
+ size, respectively.
+ (gdk_pixbuf_new_from_xpm_data): Changed the "data" argument to
+ const char **.
+
+ * gdk-pixbuf/io-gif.c (image_load_animation): Create the animation
+ with a reference count of 1.
+
+ * gdk-pixbuf/Makefile.am (libgdk_pixbuf_la_SOURCES): Added
+ gdk-pixbuf-animation.c.
+
+ * doc/tmpl/animation.sgml: Populated. It is still missing a
+ description of the overlay modes.
+
+ * doc/gdk-pixbuf-sections.txt: Added the animation section. Moved
+ the canvas item section to the end, as it will be moved later to
+ gnome-libs.
+
+ * doc/gdk-pixbuf.sgml: Added the animation section.
+
+ * doc/Makefile.am (tmpl_sources): Added tmpl/animation.sgml.
+
1999-12-26 Peter Teichman <pat@gnu.org>
* gdk-pixbuf/Makefile.am (libpixbuf_tiff_la_LIBADD): add
1999-12-08 Arjan van de Ven <arjan@fenrus.demon.nl>
- * gdk-pixbuf/gdk-pixbuf-drawable.c : Fixed the red/green/red
+ * gdk-pixbuf/gdk-pixbuf-drawable.c : Fixed the red/green/red
bug on two occasions.
- * gdk-pixbuf/io-ras.c: Changed from the custom be32_to_cpu
+ * gdk-pixbuf/io-ras.c: Changed from the custom be32_to_cpu
function to the generic glib one.
1999-12-08 Federico Mena Quintero <federico@redhat.com>
if INSIDE_GNOME_LIBS
testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS)
+testanimation_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule
else
testpixbuf_LDADD = $(LDADDS) $(LIBART_LIBS) $(GNOME_LIBS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS) $(GNOME_LIBS)
-endif
-
-if INSIDE_GNOME_LIBS
-testanimation_LDADD = $(LDADDS) $(LIBART_LIBS) -lgmodule
-testanimation_drawable_LDADD = $(LDADDS)
-else
testanimation_LDADD = $(LDADDS) $(LIBART_LIBS) $(GNOME_LIBS) -lgmodule
-testanimation_drawable_LDADD = $(LDADDS) $(GNOME_LIBS)
endif
libgdk_pixbuf_la_SOURCES = \
gdk-pixbuf.c \
+ gdk-pixbuf-animation.c \
gdk-pixbuf-data.c \
gdk-pixbuf-drawable.c \
gdk-pixbuf-io.c \
--- /dev/null
+/* GdkPixbuf library - Simple animation support
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Jonathan Blandford <jrb@redhat.com>
+ * Havoc Pennington <hp@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gdk-pixbuf-io.h"
+
+\f
+
+/**
+ * gdk_pixbuf_animation_new_from_file:
+ * @filename: Name of file to load.
+ *
+ * Creates a new animation by loading it from a file. The file format is
+ * detected automatically. If the file's format does not support multi-frame
+ * images, then an animation with a single frame will be created.
+ *
+ * Return value: A newly created animation with a reference count of 1, or NULL
+ * if any of several error conditions ocurred: the file could not be opened,
+ * there was no loader for the file's format, there was not enough memory to
+ * allocate the image buffer, or the image file contained invalid data.
+ **/
+GdkPixbufAnimation *
+gdk_pixbuf_animation_new_from_file (const char *filename)
+{
+ GdkPixbufAnimation *animation;
+ int size;
+ FILE *f;
+ guchar buffer [128];
+ GdkPixbufModule *image_module;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ f = fopen (filename, "r");
+ if (!f)
+ return NULL;
+
+ size = fread (&buffer, 1, sizeof (buffer), f);
+
+ if (size == 0) {
+ fclose (f);
+ return NULL;
+ }
+
+ image_module = gdk_pixbuf_get_module (buffer, size);
+ if (!image_module) {
+ g_warning ("Unable to find handler for file: %s", filename);
+ fclose (f);
+ return NULL;
+ }
+
+ if (image_module->module == NULL)
+ gdk_pixbuf_load_module (image_module);
+
+ if (image_module->load_animation == NULL) {
+ GdkPixbuf *pixbuf;
+ GdkPixbufFrame *frame;
+
+ /* Keep this logic in sync with gdk_pixbuf_new_from_file() */
+
+ if (image_module->load == NULL) {
+ fclose (f);
+ return NULL;
+ }
+
+ fseek (f, 0, SEEK_SET);
+ pixbuf = (* image_module->load) (f);
+ fclose (f);
+
+ if (pixbuf)
+ g_assert (pixbuf->ref_count > 0);
+ else
+ return NULL;
+
+ frame = g_new (GdkPixbufFrame, 1);
+ frame->pixbuf = pixbuf;
+ frame->x_offset = 0;
+ frame->y_offset = 0;
+ frame->delay_time = -1;
+ frame->action = GDK_PIXBUF_FRAME_RETAIN;
+
+ animation = g_new (GdkPixbufAnimation, 1);
+ animation->ref_count = 1;
+ animation->n_frames = 1;
+ animation->frames = g_list_prepend (NULL, frame);
+ } else {
+ fseek (f, 0, SEEK_SET);
+ animation = (* image_module->load_animation) (f);
+ fclose (f);
+ }
+
+ return animation;
+}
+
+/**
+ * gdk_pixbuf_animation_ref:
+ * @animation: An animation.
+ *
+ * Adds a reference to an animation. It must be released afterwards using
+ * gdk_pixbuf_animation_unref().
+ **/
+void
+gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation)
+{
+ g_return_if_fail (animation != NULL);
+ g_return_if_fail (animation->ref_count > 0);
+
+ animation->ref_count++;
+}
+
+/**
+ * gdk_pixbuf_animation_unref:
+ * @animation: An animation.
+ *
+ * Removes a reference from an animation. It will be destroyed when the
+ * reference count drops to zero. At that point, all the frames in the
+ * animation will be freed and their corresponding pixbufs will be unreferenced.
+ **/
+void
+gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation)
+{
+ g_return_if_fail (animation != NULL);
+ g_return_if_fail (animation->ref_count > 0);
+
+ animation->ref_count--;
+
+ if (animation->ref_count == 0) {
+ GList *l;
+ GdkPixbufFrame *frame;
+
+ for (l = animation->frames; l; l = l->next) {
+ frame = l->data;
+ gdk_pixbuf_unref (frame->pixbuf);
+ g_free (frame);
+ }
+
+ g_list_free (animation->frames);
+ g_free (animation);
+ }
+}
GModule *module;
gpointer load_sym;
- g_return_if_fail(image_module->module == NULL);
+ g_return_if_fail (image_module->module == NULL);
module_name = g_strconcat ("pixbuf-", image_module->module_name, NULL);
path = g_module_build_path (PIXBUF_LIBDIR, module_name);
module = g_module_open (path, G_MODULE_BIND_LAZY);
if (!module) {
/* Debug feature, check in present working directory */
- g_free(path);
- path = g_module_build_path("", module_name);
- module = g_module_open(path, G_MODULE_BIND_LAZY);
+ g_free (path);
+ path = g_module_build_path ("", module_name);
+ module = g_module_open (path, G_MODULE_BIND_LAZY);
if (!module) {
- g_warning ("Unable to load module: %s: %s", path, g_module_error());
+ g_warning ("Unable to load module: %s: %s", path, g_module_error ());
g_free (module_name);
- g_free(path);
+ g_free (path);
return;
}
- g_free(path);
+ g_free (path);
} else {
g_free (path);
}
\f
GdkPixbufModule *
-gdk_pixbuf_get_module (gchar *buffer, gint size)
+gdk_pixbuf_get_module (guchar *buffer, guint size)
{
- gint i;
+ int i;
for (i = 0; file_formats [i].module_name; i++) {
if ((* file_formats [i].format_check) (buffer, size))
return &(file_formats[i]);
}
+
return NULL;
}
gdk_pixbuf_new_from_file (const char *filename)
{
GdkPixbuf *pixbuf;
- gint size;
+ int size;
FILE *f;
- char buffer [128];
+ guchar buffer [128];
GdkPixbufModule *image_module;
+ g_return_val_if_fail (filename != NULL, NULL);
+
f = fopen (filename, "r");
if (!f)
return NULL;
size = fread (&buffer, 1, sizeof (buffer), f);
-
if (size == 0) {
fclose (f);
return NULL;
}
image_module = gdk_pixbuf_get_module (buffer, size);
- if (image_module){
- if (image_module->module == NULL)
- gdk_pixbuf_load_module (image_module);
-
- if (image_module->load == NULL) {
- fclose (f);
- return NULL;
- }
-
- fseek (f, 0, SEEK_SET);
- pixbuf = (* image_module->load) (f);
+ if (!image_module) {
+ g_warning ("Unable to find handler for file: %s", filename);
fclose (f);
+ return NULL;
+ }
- if (pixbuf)
- g_assert (pixbuf->ref_count != 0);
+ if (image_module->module == NULL)
+ gdk_pixbuf_load_module (image_module);
- return pixbuf;
- } else {
- g_warning ("Unable to find handler for file: %s", filename);
+ if (image_module->load == NULL) {
+ fclose (f);
+ return NULL;
}
+ fseek (f, 0, SEEK_SET);
+ pixbuf = (* image_module->load) (f);
fclose (f);
- return NULL;
+
+ if (pixbuf)
+ g_assert (pixbuf->ref_count > 0);
+
+ return pixbuf;
}
/**
* Return value: A newly-created pixbuf with a reference count of 1.
**/
GdkPixbuf *
-gdk_pixbuf_new_from_xpm_data (const gchar **data)
+gdk_pixbuf_new_from_xpm_data (const char **data)
{
- GdkPixbuf *(* load_xpm_data) (const gchar **data);
- GdkPixbuf *pixbuf;
-
- if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) {
- gdk_pixbuf_load_module(&file_formats[XPM_FILE_FORMAT_INDEX]);
- }
-
- if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) {
- g_warning("Can't find gdk-pixbuf module for parsing inline XPM data");
- return NULL;
- } else if (file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data == NULL) {
- g_warning("gdk-pixbuf XPM module lacks XPM data capability");
- return NULL;
- } else {
- load_xpm_data = file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data;
- }
-
- pixbuf = load_xpm_data(data);
-
- return pixbuf;
-}
-
+ GdkPixbuf *(* load_xpm_data) (const char **data);
+ GdkPixbuf *pixbuf;
-/**
- * gdk_pixbuf_animation_new_from_file:
- * @filename: The filename.
- *
- * Creates a new @GdkPixbufAnimation with @filename loaded as the animation. If
- * @filename doesn't exist or is an invalid file, the @n_frames member will be
- * 0. If @filename is a static image (and not an animation) then the @n_frames
- * member will be 1.
- *
- * Return value: A newly created GdkPixbufAnimation.
- **/
-GdkPixbufAnimation *
-gdk_pixbuf_animation_new_from_file (const gchar *filename)
-{
- GdkPixbufAnimation *animation;
- gint size;
- FILE *f;
- char buffer [128];
- GdkPixbufModule *image_module;
+ if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL)
+ gdk_pixbuf_load_module (&file_formats[XPM_FILE_FORMAT_INDEX]);
- f = fopen (filename, "r");
- if (!f)
+ if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) {
+ g_warning ("Can't find gdk-pixbuf module for parsing inline XPM data");
return NULL;
-
- size = fread (&buffer, 1, sizeof (buffer), f);
-
- if (size == 0) {
- fclose (f);
+ } else if (file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data == NULL) {
+ g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
return NULL;
- }
+ } else
+ load_xpm_data = file_formats[XPM_FILE_FORMAT_INDEX].load_xpm_data;
- image_module = gdk_pixbuf_get_module (buffer, size);
- if (image_module){
- if (image_module->module == NULL)
- gdk_pixbuf_load_module (image_module);
-
- if (image_module->load_animation == NULL) {
- GdkPixbufFrame *frame;
- if (image_module->load == NULL) {
- fclose (f);
- return NULL;
- }
- animation = g_new (GdkPixbufAnimation, 1);
- frame = g_new (GdkPixbufFrame, 1);
-
- animation->n_frames = 1;
- animation->frames = g_list_prepend (NULL, (gpointer) frame);
-
- frame->x_offset = 0;
- frame->y_offset = 0;
- frame->delay_time = -1;
- frame->action = GDK_PIXBUF_FRAME_RETAIN;
-
- fseek (f, 0, SEEK_SET);
- frame->pixbuf = (* image_module->load) (f);
- fclose (f);
- } else {
- fseek (f, 0, SEEK_SET);
- animation = (* image_module->load_animation) (f);
- fclose (f);
- }
-
- return animation;
- } else {
- g_warning ("Unable to find handler for file: %s", filename);
- }
-
- fclose (f);
- return NULL;
+ pixbuf = (* load_xpm_data) (data);
+ return pixbuf;
}
\f
typedef void (* ModulePreparedNotifyFunc) (GdkPixbuf *pixbuf, gpointer user_data);
-typedef void (* ModuleUpdatedNotifyFunc) (GdkPixbuf *pixbuf, gpointer user_data, guint x, guint y, guint width, guint height);
+typedef void (* ModuleUpdatedNotifyFunc) (GdkPixbuf *pixbuf, gpointer user_data,
+ guint x, guint y,
+ guint width, guint height);
typedef struct _GdkPixbufModule GdkPixbufModule;
struct _GdkPixbufModule {
gboolean (* format_check) (guchar *buffer, int size);
GModule *module;
GdkPixbuf *(* load) (FILE *f);
- GdkPixbuf *(* load_xpm_data) (const gchar **data);
+ GdkPixbuf *(* load_xpm_data) (const char **data);
/* Incremental loading */
- gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, gpointer user_data);
- void (* stop_load) (gpointer context);
- gboolean (* load_increment)(gpointer context, const gchar *buf, guint size);
+
+ gpointer (* begin_load) (ModulePreparedNotifyFunc prepare_func,
+ ModuleUpdatedNotifyFunc update_func,
+ gpointer user_data);
+ void (* stop_load) (gpointer context);
+ gboolean (* load_increment) (gpointer context, const guchar *buf, guint size);
/* Animation loading */
GdkPixbufAnimation *(* load_animation) (FILE *f);
};
-GdkPixbufModule *gdk_pixbuf_get_module (gchar *buffer,
- gint size);
-void gdk_pixbuf_load_module (GdkPixbufModule *image_module);
-
+GdkPixbufModule *gdk_pixbuf_get_module (guchar *buffer, guint size);
+void gdk_pixbuf_load_module (GdkPixbufModule *image_module);
\f
GdkPixbuf *pixbuf;
GdkPixbufAnimation *animation;
gboolean closed;
- gchar header_buf[LOADER_HEADER_SIZE];
+ guchar header_buf[LOADER_HEADER_SIZE];
gint header_buf_offset;
GdkPixbufModule *image_module;
gpointer context;
}
static int
-gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const gchar *buf, size_t count)
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const guchar *buf, size_t count)
{
int nbytes;
GdkPixbufLoaderPrivate *priv = loader->private;
* cannot parse the buffer.
**/
gboolean
-gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const gchar *buf, size_t count)
+gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, size_t count)
{
GdkPixbufLoaderPrivate *priv;
GtkType gdk_pixbuf_loader_get_type (void);
GdkPixbufLoader *gdk_pixbuf_loader_new (void);
gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader,
- const gchar *buf,
+ const guchar *buf,
size_t count);
GdkPixbuf *gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader);
GdkPixbufAnimation *gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader);
ArtPixFormat
gdk_pixbuf_get_format (GdkPixbuf *pixbuf)
{
- /* Unfortunately, there's nothing else to return */
g_return_val_if_fail (pixbuf != NULL, ART_PIX_RGB);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->format);
+ return pixbuf->art_pixbuf->format;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->n_channels);
+ return pixbuf->art_pixbuf->n_channels;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->has_alpha);
+ return pixbuf->art_pixbuf->has_alpha;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->bits_per_sample);
+ return pixbuf->art_pixbuf->bits_per_sample;
}
/**
g_return_val_if_fail (pixbuf != NULL, NULL);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->pixels);
+ return pixbuf->art_pixbuf->pixels;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->width);
+ return pixbuf->art_pixbuf->width;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->height);
+ return pixbuf->art_pixbuf->height;
}
/**
g_return_val_if_fail (pixbuf != NULL, -1);
g_assert (pixbuf->art_pixbuf != NULL);
- return (pixbuf->art_pixbuf->rowstride);
+ return pixbuf->art_pixbuf->rowstride;
}
-
-/**
- * gdk_pixbuf_animation_destroy:
- * @animation: An animation.
- * @free_frames: Keep the frames.
- *
- * Destroys the animation. If @free_frames is set, then the actual image data
- * will be free'd as well.
- *
- **/
-void
-gdk_pixbuf_animation_destroy (GdkPixbufAnimation *animation,
- gboolean free_frames)
-{
- GList *ptr;
-
- g_return_if_fail (animation != NULL);
-
- for (ptr = animation->frames; ptr; ptr = g_list_next (ptr)) {
- if (free_frames)
- gdk_pixbuf_unref (((GdkPixbufFrame *)ptr->data)->pixbuf);
- g_free (ptr->data);
- }
- g_list_free (animation->frames);
-
- g_free (animation);
-}
-
typedef struct _GdkPixbufFrame GdkPixbufFrame;
typedef struct _GdkPixbufAnimation GdkPixbufAnimation;
-typedef enum
-{
- GDK_PIXBUF_FRAME_RETAIN,
- GDK_PIXBUF_FRAME_DISPOSE,
- GDK_PIXBUF_FRAME_REVERT
-} GdkPixbufFrameAction;
-
-struct _GdkPixbuf
-{
+struct _GdkPixbuf {
/* Reference count */
int ref_count;
ArtPixBuf *art_pixbuf;
};
+/* GIF-like animation overlay modes for frames */
+typedef enum {
+ GDK_PIXBUF_FRAME_RETAIN,
+ GDK_PIXBUF_FRAME_DISPOSE,
+ GDK_PIXBUF_FRAME_REVERT
+} GdkPixbufFrameAction;
-struct _GdkPixbufFrame
-{
+struct _GdkPixbufFrame {
+ /* The pixbuf with this frame's image data */
GdkPixbuf *pixbuf;
- gushort x_offset;
- gushort y_offset;
- gint delay_time;
+ /* Offsets for overlaying onto the animation's area */
+ int x_offset;
+ int y_offset;
+
+ /* Frame duration in ms */
+ int delay_time;
+
+ /* Overlay mode */
GdkPixbufFrameAction action;
};
+struct _GdkPixbufAnimation {
+ /* Reference count */
+ int ref_count;
-struct _GdkPixbufAnimation
-{
+ /* Number of frames */
int n_frames;
+
+ /* List of GdkPixbufFrame structures */
GList *frames;
};
void gdk_pixbuf_ref (GdkPixbuf *pixbuf);
void gdk_pixbuf_unref (GdkPixbuf *pixbuf);
-/* Constructors */
/* Wrap a libart pixbuf */
-
GdkPixbuf *gdk_pixbuf_new_from_art_pixbuf (ArtPixBuf *art_pixbuf);
/* Create a blank pixbuf with an optimal rowstride and a new buffer */
-
GdkPixbuf *gdk_pixbuf_new (ArtPixFormat format, gboolean has_alpha, int bits_per_sample,
int width, int height);
/* Simple loading */
-GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename);
-GdkPixbuf *gdk_pixbuf_new_from_data (guchar *data,
- ArtPixFormat format,
- gboolean has_alpha,
- int width, int height,
- int rowstride,
- ArtDestroyNotify dfunc,
- gpointer dfunc_data);
-GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const gchar **data);
+GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename);
+
+GdkPixbuf *gdk_pixbuf_new_from_data (guchar *data,
+ ArtPixFormat format,
+ gboolean has_alpha,
+ int width, int height,
+ int rowstride,
+ ArtDestroyNotify dfunc,
+ gpointer dfunc_data);
-/* Adding or removing alpha */
+GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data);
+/* Adding an alpha channel */
GdkPixbuf *gdk_pixbuf_add_alpha (GdkPixbuf *pixbuf, gboolean substitute_color,
guchar r, guchar g, guchar b);
/* Rendering to a drawable */
+/* Alpha compositing mode */
typedef enum {
GDK_PIXBUF_ALPHA_BILEVEL,
GDK_PIXBUF_ALPHA_FULL
GdkRgbDither dither,
int x_dither, int y_dither);
-
/* Fetching a region from a drawable */
GdkPixbuf *gdk_pixbuf_get_from_drawable (GdkPixbuf *dest,
GdkDrawable *src, GdkColormap *cmap,
int dest_x, int dest_y,
int width, int height);
-\f
-
-/* Animation loading */
+/* Animation support */
-GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename);
-void gdk_pixbuf_animation_destroy (GdkPixbufAnimation *animation,
- gboolean free_frames);
+GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename);
+void gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation);
+void gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation);
\f
return retval;
} else {
#ifdef IO_GIFDEBUG
-// g_print ("\tlooking for %d bytes. size == %d, ptr == %d\n", len, context->size, context->ptr);
+/* g_print ("\tlooking for %d bytes. size == %d, ptr == %d\n", len, context->size, context->ptr); */
#endif
if ((context->size - context->ptr) >= len) {
#ifdef IO_GIFDEBUG
GetDataBlock (GifContext *context,
unsigned char *buf)
{
-// unsigned char count;
+/* unsigned char count; */
if (!gif_read (context, &context->block_count, 1)) {
/*g_message (_("GIF: error in getting DataBlock size\n"));*/
{
GifContext *context = (GifContext *) data;
+ /* FIXME: free the animation data */
+
if (context->pixbuf)
gdk_pixbuf_unref (context->pixbuf);
-// g_free (context->buf);
+/* g_free (context->buf); */
g_free (context);
}
context = new_context ();
context->animation = g_new (GdkPixbufAnimation, 1);
+ context->animation->ref_count = 1;
context->animation->n_frames = 0;
context->animation->frames = NULL;
context->file = file;
*
* Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
* Cody Russell <bratsche@dfw.net>
- * Federico
+ * Federico Mena-Quintero <federico@gimp.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
if (v->red_mask == 0xf800 && v->green_mask == 0x7e0 && v->blue_mask == 0x1f
&& image->bpp == 16)
bank = 3;
- break;
+ break;
case 24:
case 32:
if (v->red_mask == 0xff0000 && v->green_mask == 0xff00 && v->blue_mask == 0xff
int width, int height)
{
GdkWindowType window_type;
- gint src_width, src_height;
+ int src_width, src_height;
ArtPixBuf *apb = NULL;
GdkImage *image;
int rowstride, bpp, alpha;
if (window_type != GDK_WINDOW_PIXMAP) {
int ret;
- gint src_xorigin, src_yorigin;
+ int src_xorigin, src_yorigin;
int screen_width, screen_height;
int screen_srcx, screen_srcy;
GdkPixbuf *pixbuf;
GdkPixbufAnimation *animation;
gboolean closed;
- gchar header_buf[LOADER_HEADER_SIZE];
+ guchar header_buf[LOADER_HEADER_SIZE];
gint header_buf_offset;
GdkPixbufModule *image_module;
gpointer context;
}
static int
-gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const gchar *buf, size_t count)
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const guchar *buf, size_t count)
{
int nbytes;
GdkPixbufLoaderPrivate *priv = loader->private;
* cannot parse the buffer.
**/
gboolean
-gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const gchar *buf, size_t count)
+gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, size_t count)
{
GdkPixbufLoaderPrivate *priv;
GtkType gdk_pixbuf_loader_get_type (void);
GdkPixbufLoader *gdk_pixbuf_loader_new (void);
gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader,
- const gchar *buf,
+ const guchar *buf,
size_t count);
GdkPixbuf *gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader);
GdkPixbufAnimation *gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader);